package com.umeox.watch.moto.sos;

import android.content.Context;
import android.os.AsyncTask;
import android.text.TextUtils;

import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.FileUtils;
import com.umeox.moto.common.utils.NetUtils;
import com.umeox.watch.moto.dataservice.interfaces.IPullApiClient;
import com.umeox.watch.moto.dataservice.proxy.PullApiClientProxy;
import com.umeox.watch.moto.sos.task.LocationTask;
import com.umeox.watch.moto.sos.task.RecordTask;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class SOSService implements RecordTask.RecordListener, LocationTask.LocationListener {
    private final LocationTask locTask;
    private final RecordTask recordTask;
    private final SOSCallback callback;

    private final Executor executor;
    private final CountDownLatch latch = new CountDownLatch(2);

    private IPullApiClient apiClient;
    private String sosEid;
    private String fileUrl;
    private int recordMaxDurationInMills;

    public boolean wifiEnabledByMyself = false;
    private static final String TAG = "SOSService";
    private AtomicBoolean sosrResult = new AtomicBoolean(false);

    private SOSService(int maxDurationMs, SOSCallback callback, Context context) {
        this.callback = callback;
        executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(), new ThreadFactory() {
            private final AtomicInteger mCount = new AtomicInteger(1);

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "SOS Executor #" + mCount.getAndIncrement());
            }
        });
        recordMaxDurationInMills = maxDurationMs <= 1000 ? 30000 : maxDurationMs;
        locTask = LocationTask.createTask();
        recordTask = RecordTask.createTask(recordMaxDurationInMills, context);
        recordTask.setOnTickListener(this);
        apiClient = PullApiClientProxy.fetchBinder();
        enableWIFI();
    }

    public static SOSService createTask(int maxDurationMs, SOSCallback callback, Context context) {
        return new SOSService(maxDurationMs, callback, context);
    }

    public void startService() {
        executor.execute(() -> {
            recordTask.start();
            if (latch.getCount() > 0) {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            callback.onFinish(sosrResult.get());
        });
    }


    @Override
    public void onStart() {
        onTick(recordMaxDurationInMills);
    }

    @Override
    public void onError() {
        onRecordEnd();
    }

    @Override
    public void onEnd(String filePath) {
        onRecordEnd();
        AsyncTask.execute(() -> {
            try {
                fileUrl = apiClient.uploadSOSFile(filePath);
                Logger.d("上报SOS录音完成>>>fileUrl=" + fileUrl + ",eid=" + sosEid);
                if (!TextUtils.isEmpty(fileUrl) && !sosEid.equals("0")) {
                    //上报SOSR事件
                    FileUtils.deleteFile(filePath);
                    if (apiClient.uploadSOSR(sosEid, fileUrl)) {
                        sosrResult.set(true);
                        latch.countDown();
                        //补发SOS2
                        apiClient.requestSOS2Location(sosEid);
                    } else {
                        sosrResult.compareAndSet(true, false);
                        latch.countDown();
                    }
                } else {
                    latch.countDown();
                    Logger.i("上报SOS录音失败>>>");
                }
            } catch (Exception e) {
                latch.countDown();
                e.printStackTrace();
                Logger.i("上报SOS录音失败>>>" + e.getMessage());
            }
        });
    }

    private void onRecordEnd() {
        latch.countDown();
        recordTask.release();
    }

    @Override
    public void onTick(long millisUntilFinished) {
        int secsUntilFinished = (int) (millisUntilFinished / 1000);
        callback.onTick(secsUntilFinished, (float) (recordMaxDurationInMills - millisUntilFinished) / recordMaxDurationInMills);
    }

    @Override
    public void onResult(byte[] data) {
        disableWIFI();
        latch.countDown();
        try {
            sosEid = apiClient.uploadSosLocation(data);
            Logger.d("上报SOS位置完成>>>" + sosEid);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void startLocation() {
        locTask.getLocationAsync(SOSService.this);
    }

    public void cancel() {
        recordTask.cancel();
    }

    public interface SOSCallback {
        void onTick(int secsUntilFinished, float percent);

        void onFinish(boolean state);
    }

    public void enableWIFI() {
        // 判断wifi是否打开，未打开则自动打开
        final boolean isWifiEnabled = NetUtils.isWifiEnabled();
        if (!isWifiEnabled) {
            try {
                Logger.i(">>>打开Wi-Fi.");
                NetUtils.setWifiEnabled(true);
                wifiEnabledByMyself = true;
            } catch (Exception e) {
                Logger.e(">>>打开Wi-Fi失败:" + e.getMessage());
            }
        }
    }

    private void disableWIFI() {
        final boolean isWifiEnabled = NetUtils.isWifiEnabled();
        try {
            if (isWifiEnabled && wifiEnabledByMyself) {
                NetUtils.setWifiEnabled(false);
                wifiEnabledByMyself = false;
                Logger.i(">>>关闭WIFI");
            }
        } catch (Exception e) {
            e.printStackTrace();
            Logger.e(">>>关闭WIFI报错:" + e.getMessage());
        }
    }
}
